import static org.junit.Assert.*;

import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;


public class PopulationTest {

	Population population;
	
	@Before
	public void setUp() throws Exception {
		population = new Population(new int[]{ 2, 3, 1});
		Population.PopulationSector populationSector000 = population.new PopulationSector(5,1.0f); 
		Population.PopulationSector populationSector010 = population.new PopulationSector(4,0.5f); 
		Population.PopulationSector populationSector020 = population.new PopulationSector(6,0.3f); 
		Population.PopulationSector populationSector100 = population.new PopulationSector(7,0.2f); 
		Population.PopulationSector populationSector110 = population.new PopulationSector(3,0.8f); 
		Population.PopulationSector populationSector120 = population.new PopulationSector(10,0.2f); 
		population.setSector(new int[]{0,0,0}, populationSector000);
		population.setSector(new int[]{0,1,0}, populationSector010);
		population.setSector(new int[]{0,2,0}, populationSector020);
		population.setSector(new int[]{1,0,0}, populationSector100);
		population.setSector(new int[]{1,1,0}, populationSector110);
		population.setSector(new int[]{1,2,0}, populationSector120);

		
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testSetSector() {
		Population.PopulationSector populationSector100New = population.new PopulationSector(3,0.5f);
		population.setSector(new int[]{1, 0, 0}, populationSector100New);
		Population.PopulationSector populationSector = population.getSector(new int[]{1, 0, 0});
		assertEquals(populationSector.getSize(), populationSector100New.getSize());
		assertEquals(populationSector.getPower(), populationSector100New.getPower());
	}

	@Test
	public void testGetSector() {
		Population.PopulationSector populationSector100 = population.new PopulationSector(7,0.2f); 
		Population.PopulationSector populationSector = population.getSector(new int[]{1, 0, 0});
		assertEquals(populationSector.getSize(), populationSector100.getSize());
		assertEquals(populationSector.getPower(), populationSector100.getPower());
	}

	@Test
	public void testComputeCoalitions() {
		int counter = 0;
		List<Population.CoalitionWithInfo> coalitionsWithInfo = population.computeCoalitions();
		for(Population.CoalitionWithInfo coalitionWithInfo : coalitionsWithInfo){
			System.out.println("Coalition " + counter);
			System.out.println("size:  " + coalitionWithInfo.getCoalitionSize());
			System.out.println("modulated size:  " + coalitionWithInfo.getCoalitionModulatedSize());
			System.out.println(coalitionWithInfo.getCoalition().toString());
			counter++;
		}
	}
	
	@Test
	public void testGetWinningCoalition() {
		Population.CoalitionWithInfo coalitionWithInfo = population.getWinningCoalition();
		if(coalitionWithInfo == null){
			System.out.println("no feasible winnning coalition"); return;
		}		
		System.out.println("Winning Coalition: ");
		System.out.println("size:  " + coalitionWithInfo.getCoalitionSize());
		System.out.println("modulated size:  " + coalitionWithInfo.getCoalitionModulatedSize());
		System.out.println("total population modulated size:  " + population.getTotalModulatedSize());
		System.out.println("fractional power:  " + 
				coalitionWithInfo.getCoalitionModulatedSize()/population.getTotalModulatedSize());
		System.out.println(coalitionWithInfo.getCoalition().toString());
	}	
	
	@Test
	public void testGetPreferredCoalitions() {
		int counter = 0;
		int[] indices = Population.getIndexArrayWithOneValue(population.dimensionSizes.length, 0, -1);
		List<int[]> allSectorIndices = RecursiveAccess.generateAllPermutations(indices, population.dimensionSizes);
		for(int[] sectorIndices: allSectorIndices){
			Population.CoalitionWithInfo coalitionWithInfo = population.getPreferredCoalition(sectorIndices);
			System.out.println("Sector: " + counter + "; indices: " + Population.printIntArray(sectorIndices));
			if(coalitionWithInfo == null){
				System.out.println("no feasible coalition"); counter++; continue;
			}
			System.out.println("preferred coalition size:  " + coalitionWithInfo.getCoalitionSize());
			System.out.println("preferred coalition modulated size:  " + coalitionWithInfo.getCoalitionModulatedSize());
			System.out.println("total population modulated size:  " + population.getTotalModulatedSize());
			System.out.println("fractional power:  " + 
					coalitionWithInfo.getCoalitionModulatedSize()/population.getTotalModulatedSize());
			System.out.println(coalitionWithInfo.getCoalition().toString());
			counter++;
		}
	}	

}
